package logger

import (
	"github.com/natefinch/lumberjack"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"os"
)

var std *zap.Logger

type LoggerConfig lumberjack.Logger

func init() {
	Default()
}

func Default() {
	lumberJackLogger := &lumberjack.Logger{
		Filename:   "./log/app.log",
		LocalTime:  true,  // 本地时间文件名
		MaxSize:    10,    // M
		MaxBackups: 1,     // 最大备份数量
		MaxAge:     1,     // 最大备份天数
		Compress:   false, // 是否压缩
	}
	std = create(zapcore.DebugLevel, lumberJackLogger)
}

func NewInfoLevel(lumberJackLogger *LoggerConfig, opts ...zap.Option) {
	std = create(zapcore.InfoLevel, (*lumberjack.Logger)(lumberJackLogger), opts...)
}

func NewDebugLevel(lumberJackLogger *LoggerConfig, opts ...zap.Option) {
	std = create(zapcore.DebugLevel, (*lumberjack.Logger)(lumberJackLogger), opts...)
}

func create(levelEnabler zapcore.LevelEnabler, lumberJackLogger *lumberjack.Logger, opts ...zap.Option) *zap.Logger {
	// 引擎
	encoderConfig := zap.NewProductionEncoderConfig()
	encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder // 修改日期配置
	encoder := zapcore.NewJSONEncoder(encoderConfig)

	// 写入文件
	//file, _ := os.OpenFile("./test.log", os.O_CREATE|os.O_APPEND|os.O_RDWR, 8744)
	//writeSyncer := zapcore.AddSync(file)

	// 实现文件切割/归类
	//lumberJackLogger := &lumberjack.Logger{
	//	Filename:   "./log/app.log",
	//	LocalTime:  true,  // 本地时间文件名
	//	MaxSize:    10,    // M
	//	MaxBackups: 1,     // 最大备份数量
	//	MaxAge:     1,     // 最大备份天数
	//	Compress:   false, // 是否压缩
	//}
	writeSyncer := zapcore.AddSync(lumberJackLogger)

	// 初始化 Core
	// encoder: 引擎
	// writeSyncer: 写入配置
	// Level: 写入级别，什么级别的日志才可以被记录
	var core zapcore.Core

	if levelEnabler == zapcore.DebugLevel {
		// 开发阶段
		// 把日志把日志持久化到文件，并输出到控制台
		core = zapcore.NewTee(
			zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel), // 开启 debug 级别，持久化到文件
			zapcore.NewCore(
				zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig()), // 开发阶段配置
				zapcore.Lock(os.Stdout), zapcore.DebugLevel, // 输出到控制台
			),
		)
	} else {
		// 其他阶段
		core = zapcore.NewCore(encoder, writeSyncer, zapcore.InfoLevel) // 久化到文件
	}

	opts = append(opts, zap.AddCaller()) // 添加函数调用信息

	// 钩子
	//opts = append(opts, zap.Hooks(func(entry zapcore.Entry) error {
	//	fmt.Println("count:", 1, "msg:", entry.Message)
	//	return nil
	//}))

	// 初始化自定义日志
	return zap.New(
		core,
		opts...,
	)
}

type Field = zap.Field

func Debug(msg string, fields ...Field) { std.Debug(msg, fields...) }
func Info(msg string, fields ...Field)  { std.Info(msg, fields...) }
func Warn(msg string, fields ...Field)  { std.Warn(msg, fields...) }
func Error(msg string, fields ...Field) { std.Error(msg, fields...) }
func Panic(msg string, fields ...Field) { std.Panic(msg, fields...) }
func Fatal(msg string, fields ...Field) { std.Fatal(msg, fields...) }

func Sync() error { return std.Sync() }
